"""
无人机管理系统
重新设计的无人机状态管理和控制系统，简化原有复杂逻辑

作者：wjttdbx
版本：4.0 - 单一事实来源重构
"""
import math
from typing import List, Optional, Tuple, TYPE_CHECKING
from .config import GameConfig
from .utils import distance_between_points

if TYPE_CHECKING:
    from .units import WhiteBoat, WhiteDrone


class DroneState:
    """无人机状态枚举"""         # 停靠在母舰上，准备就绪
    FLYING = "flying"        # 飞行中
    RECHARGING = "recharging"  # 停靠在母舰上，充电中
    RETURNING = "returning"   # 飞行中，正在返航



class DroneManager:
    """
    无人机管理器
    
    统一管理所有无人机的状态转换、能源管理、起飞降落等逻辑。
    操作单一的无人机列表，作为唯一的事实来源。
    """
    
    def __init__(self):
        self.debug_mode = True  # 调试模式开关
    
    def update_all_drones(self, white_boats: List['WhiteBoat'], all_drones: List['WhiteDrone'], 
                         current_time: float, dt: float):
        """
        更新所有无人机状态
        
        Args:
            white_boats: 白方无人艇列表
            all_drones: 所有的白方无人机列表
            current_time: 当前时间
            dt: 时间步长
        """
        for drone in all_drones:
            # 跳过已退出的无人机
            if hasattr(drone, 'active') and not drone.active:
                continue
            if drone.docked_on_boat_id is not None and drone.docked_on_boat_id >= 0:
                # 无人机停靠在船上
                parent_boat = self._find_boat_by_id(drone.docked_on_boat_id, white_boats)
                self._update_docked_drone(drone, parent_boat, current_time, dt)
            else:
                # 无人机在空中飞行
                self._update_flying_drone(drone, white_boats, current_time, dt)
    
    def _update_docked_drone(self, drone: 'WhiteDrone', parent_boat: Optional['WhiteBoat'], current_time: float, dt: float):
        """更新停靠在母舰上的无人机"""
        # 母舰不存在或已退出：无人机也退出
        if parent_boat is None or not parent_boat.active:
            try:
                drone.active = False
                # 解除停靠标记，防止后续错误关联
                drone.docked_on_boat_id = -1
                if self.debug_mode:
                    print(f"[DroneManager] 无人机{drone.id}所属母舰不可用，已将无人机标记为退出(active=False)")
            finally:
                return

        # 位置和航向跟随母舰
        if parent_boat is not None:
            drone.x, drone.y, drone.heading = parent_boat.x, parent_boat.y, parent_boat.heading
            
            # 根据状态更新
            if drone.state == DroneState.RECHARGING:
                parent_frozen = parent_boat.is_frozen(current_time)
                if not parent_frozen:
                    drone.energy = min(drone.max_energy, drone.energy + drone.recharge_rate * dt)
            
            if self._is_recharge_complete(drone, current_time):
                #drone.state = DroneState.READY
                if self.debug_mode:
                    pass
                    #print(f"[DroneManager] 无人机{drone.id}充电完成，状态转为ready")

    def _update_flying_drone(self, drone: 'WhiteDrone', white_boats: List['WhiteBoat'], current_time: float, dt: float):
        """更新飞行中的无人机"""
        # 若母舰已退出/被击沉，则无人机也直接判定为退出（击沉）
        try:
            parent = None
            for b in white_boats:
                if b.id == drone.parent_boat_id:
                    parent = b
                    break
            if (parent is None) or (not parent.active):
                drone.active = False
                if self.debug_mode:
                    print(f"[DroneManager] 无人机{drone.id}飞行中其母舰已退出(boat={drone.parent_boat_id})，无人机直接记作退出(active=False)")
                return
        except Exception:
            pass

        # 消耗能量
        drone.energy = max(0, drone.energy - drone.energy_consumption_rate * dt)
        
        # 检查是否需要自动返航
        if self._should_auto_return(drone, current_time) and drone.state != DroneState.RETURNING:
            drone.state = DroneState.RETURNING
            if self.debug_mode:
                print(f"[DroneManager] 无人机{drone.id}因能量耗尽自动返航, 能量: {drone.energy:.1f}%")

        # 尝试降落（只有在返航状态下才能自动降落）
        if drone.state == DroneState.RETURNING:
            # 注意：这里的 all_drones 是一个潜在的 bug，应该从外部传入。当前暂时忽略。
            # 自动降落优先级低于手动降落，只有在没有手动降落指令时才执行
            # 自动降落默认使用最近母舰策略
            self._try_auto_land(drone, white_boats, [], current_time)

    def land_drone(self,target_boat:'WhiteBoat',drone:'WhiteDrone',current_time:float):

        """
        无人机降落
        """
        if drone.state not in [DroneState.FLYING, DroneState.RETURNING]:
            if self.debug_mode:
                print(f"[DroneManager] 无人机{drone.id}状态为 {drone.state}，不满足降落条件")
            return False
        if target_boat.is_frozen(current_time) or not target_boat.active or (drone.docked_on_boat_id >= 0 and target_boat.id == drone.docked_on_boat_id):
            if self.debug_mode:
                print(f"[DroneManager] 目标母舰{target_boat.id}状态异常，不满足降落条件")
            return False

        distance = distance_between_points(drone.x, drone.y, target_boat.x, target_boat.y)
        if distance >= GameConfig.WHITE_DRONE_LANDING_DISTANCE:
            if self.debug_mode:
                print(f"[DroneManager] 无人机{drone.id}距离目标母舰{target_boat.id}距离为 {distance:.2f} 米，不满足降落条件")
            return False
        elif drone.speed >= GameConfig.WHITE_DRONE_LANDING_SPEED:
            if self.debug_mode:
                print(f"[DroneManager] 无人机{drone.id}速度为 {drone.speed:.2f} 米/秒，不满足降落条件")
            return False
        else:
            self._execute_landing(drone, target_boat, current_time)
            if self.debug_mode:
                print(f"[DroneManager] 无人机{drone.id}降落成功")
            return True


    def launch_drone(self, boat: 'WhiteBoat', all_drones: List['WhiteDrone'], current_time: float) -> bool:
        """从指定无人艇发射无人机"""


        # 1. 找到停靠在这艘无人艇上的无人机
        drone_to_launch = None
        for d in all_drones:
            if d.docked_on_boat_id == boat.id:
                drone_to_launch = d
                break

        # 1.5 若未找到可发射的无人机，直接返回
        if drone_to_launch is None:
            if self.debug_mode:
                print(f"[DroneManager] 发射失败：无人艇{boat.id}上未找到可发射的无人机。")
            return False

        # 2. 检查无人机能量是否足够起飞
        if drone_to_launch.energy < 15.0:  # 至少需要15%能量才能起飞
            if self.debug_mode:
                print(f"[DroneManager] 发射失败：无人艇{boat.id}上的无人机能量不足({drone_to_launch.energy:.1f}%)，无法起飞（需≥15%）。")
            return False

        # 4. 执行发射
        return self._execute_launch(drone_to_launch, boat, current_time)



    def _execute_launch(self, drone: 'WhiteDrone', boat: 'WhiteBoat', current_time: float) -> bool:
        """执行发射操作"""
        # 更新无人机状态
        drone.state = DroneState.FLYING
        drone.flight_start_time = current_time
        drone.speed = GameConfig.WHITE_DRONE_TAKEOFF_SPEED
        drone.parent_boat_id = boat.id  # 设置起飞母舰
        drone.docked_on_boat_id = -1 # 离开母舰，使用-1表示未停靠
        
        # 设置无人机起飞位置为母舰位置
        drone.x, drone.y = boat.x, boat.y
        drone.heading = boat.heading  # 初始航向与母舰一致

       

        if self.debug_mode:
            print(f"[DroneManager] 无人机{drone.id}从母舰{boat.id}成功起飞，位置:({drone.x:.0f}, {drone.y:.0f})")
        return True
        
    def _try_auto_land(self, drone: 'WhiteDrone', white_boats: List['WhiteBoat'], all_drones: List['WhiteDrone'], current_time: float):

        """尝试为飞行中的无人机执行降落"""
        # 找到最近的、可用的降落平台
        target_boat = self._find_nearest_available_boat(drone, white_boats, all_drones, current_time)
        if not target_boat:
            return

        # 检查是否满足降落的物理条件
        distance = distance_between_points(drone.x, drone.y, target_boat.x, target_boat.y)
        if distance <= GameConfig.WHITE_DRONE_LANDING_DISTANCE:
            if self.debug_mode:
                print(f"[DroneManager] 无人机{drone.id}距离目标母舰{target_boat.id}距离为 {distance:.2f} 米，满足降落条件")
            drone.speed = 20 

        if (distance <= GameConfig.WHITE_DRONE_LANDING_DISTANCE and
            drone.speed <= GameConfig.WHITE_DRONE_LANDING_SPEED):
            self._execute_landing(drone, target_boat, current_time)

    def _execute_landing(self, drone: 'WhiteDrone', target_boat: 'WhiteBoat', current_time: float):
        """执行降落操作"""
        # 更新无人机状态
        drone.state = DroneState.RECHARGING
        drone.recharge_start_time = current_time
        drone.speed = 0
        drone.docked_on_boat_id = target_boat.id
        drone.x, drone.y = target_boat.x, target_boat.y # 位置与母舰同步

        # 无人艇的甲板状态现在由无人机的停靠状态间接决定
        if self.debug_mode:
            print(f"[DroneManager] 无人机{drone.id}成功降落到母舰{target_boat.id}")
            
    def _find_nearest_available_boat(self, drone: 'WhiteDrone', white_boats: List['WhiteBoat'], all_drones: List['WhiteDrone'], current_time: float) -> Optional['WhiteBoat']:
        """找到最近的、甲板可用的母舰"""
        docked_drone_locations = {d.docked_on_boat_id for d in all_drones if d.docked_on_boat_id is not None and d.docked_on_boat_id >= 0}
        
        available_boats = [
            boat for boat in white_boats 
            if boat.active and boat.id not in docked_drone_locations and not boat.is_frozen(current_time)
        ]
        
        if not available_boats:
            return None
        
        return min(available_boats, key=lambda boat: distance_between_points(drone.x, drone.y, boat.x, boat.y))
    
    def _find_parent_boat(self, drone: 'WhiteDrone', white_boats: List['WhiteBoat'], all_drones: List['WhiteDrone'], current_time: float) -> Optional['WhiteBoat']:
        """找到无人机的起飞母舰（如果可用且未被占用）"""
        # 查找无人机的起飞母舰
        for boat in white_boats:
            if boat.id == drone.parent_boat_id and boat.active and not boat.is_frozen(current_time):
                # 检查该母舰是否已被其他无人机占用
                is_occupied = False
                for d in all_drones:
                    if d.docked_on_boat_id == boat.id:
                        is_occupied = True
                        break
                
                if not is_occupied:
                    return boat
        return None
        
    def _should_auto_return(self, drone: 'WhiteDrone', current_time: float) -> bool:
        """判断无人机是否应因内部原因（能量/时间）自动返航"""
        energy_low = drone.energy <= 5.0  # 10%能量阈值
        time_exceeded = (current_time >= drone.flight_start_time + GameConfig.WHITE_DRONE_FLIGHT_TIME)
        return energy_low or time_exceeded

    def _is_recharge_complete(self, drone: 'WhiteDrone', current_time: float) -> bool:
        """检查充电是否完成"""
        energy_full = drone.energy >= drone.max_energy
        # # 确保充电达到最短时间要求
        # recharge_time_complete = (current_time >= drone.recharge_start_time + GameConfig.WHITE_DRONE_RECHARGE_TIME)
        # # 至少需要10%能量才能再次起飞
        # min_energy_for_flight = drone.energy >= 10.0
        
        # return (energy_full or recharge_time_complete) and min_energy_for_flight
        return energy_full


    def _find_boat_by_id(self, boat_id: int, white_boats: List['WhiteBoat']) -> Optional['WhiteBoat']:
        """通过ID查找无人艇"""
        for boat in white_boats:
            if boat.id == boat_id:
                return boat
        return None

    def get_drone_status(self, all_drones: List['WhiteDrone']) -> dict:
        """
        获取无人机状态统计
        
        Returns:
            dict: 状态统计信息
        """
        status = {
            'flying': 0,
            'recharging': 0,
            'returning': 0,
            'total': len(all_drones)
        }
        
        for drone in all_drones:
            if drone.state in status:
                status[drone.state] += 1
        
        return status 